home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / FILES.SWG / 0019_Self Modify EXE File.pas < prev    next >
Pascal/Delphi Source File  |  1993-07-16  |  7KB  |  157 lines

  1. ===========================================================================
  2.  BBS: Canada Remote Systems
  3. Date: 07-03-93 (11:56)             Number: 29412
  4. From: KELD R. HANSEN               Refer#: NONE
  5.   To: JON JASIUNAS                  Recvd: NO  
  6. Subj: Re: Self-modifying .EXEs       Conf: (1221) F-PASCAL
  7. ---------------------------------------------------------------------------
  8. In a message dated 28 Jun 93, Jon Jasiunas (1:273/216.0) wrote:
  9.  
  10.  > Here's the code I use for my self-modifying .EXEs.  I've used it
  11.  > successfully in several applications.
  12.  
  13. It works fine (I have one similar of my own), but it doesn't take care of DPMI
  14. programs and won't work if your "customer" PKLITEs the program.
  15.  
  16. TYPE
  17.   ExeHeaderDOS          = RECORD
  18.                 { 00 }      Signature           : ARRAY[1..2] OF CHAR;
  19.                 { 02 }      LastPageSize        : WORD;
  20.                 { 04 }      Pages               : WORD;
  21.                 { 06 }      RelocItems          : WORD;
  22.                 { 08 }      HeaderSizePara      : WORD;
  23.                 { 0A }      MinMemPara          : WORD;
  24.                 { 0C }      MaxMemPara          : WORD;
  25.                 { 0E }      EntrySS             : WORD;
  26.                 { 10 }      EntrySP             : WORD;
  27.                 { 12 }      CheckSum            : WORD;
  28.                 { 14 }      EntryIP             : WORD;
  29.                 { 16 }      EntryCS             : WORD;
  30.                 { 18 }      FirstRelocItemOfs   : WORD;
  31.                 { 1A }      OverlayNumber       : WORD;
  32.                             Reserved            : ARRAY[$1C..$23] OF BYTE;
  33.                 { 24 }      IdentifierOEM       : WORD;
  34.                 { 26 }      InformationOEM      : WORD;
  35.                             ReservedToo         : ARRAY[$28..$3B] OF BYTE;
  36.                 { 3C }      NewExeHeaderOfs     : LONGINT
  37.                           END;
  38.   ExeHeaderOS2          = RECORD
  39.                             Signature           : ARRAY[1..2] OF CHAR;
  40.                             LinkerMajorVers     : BYTE;
  41.                             LinkerMinorVers     : BYTE;
  42.                             EntryTableOfs       : WORD;
  43.                             EntryTableSize      : WORD;
  44.                             CRC                 : LONGINT;
  45.                             ModuleFlags         : WORD;
  46.                             SegmentNoDGROUP     : WORD;
  47.                             HeapSize            : WORD;
  48.                             StackSize           : WORD;
  49.                             EntryIP             : WORD;
  50.                             EntryCS             : WORD;
  51.                             EntrySP             : WORD;
  52.                             EntrySS             : WORD;
  53.                             SegmentTableEntries : WORD;
  54.                             ModuleRefEntries    : WORD;
  55.                             NonResNameTableSize : WORD;
  56.                             SegTableOfs         : WORD;
  57.                             ResourceTableOfs    : WORD;
  58.                             ResNamesTableOfs    : WORD;
  59.                             ModuleRefTableOfs   : WORD;
  60.                             ImpNamesTableOfs    : WORD;
  61.                             NonResNamesTableOfs : LONGINT;
  62.                             MovableEntryPoints  : WORD;
  63.                             AlignmentUnitPower  : WORD;
  64.                             ResourceTableEntries: WORD;
  65.                             TargetOS            : BYTE;
  66.                             WindowsFlags        : BYTE;
  67.                             FastLoadStart       : WORD;
  68.                             FastLoadSize        : WORD;
  69.                             Reserved            : WORD;
  70.                             WindowsVers         : WORD
  71.                           END;
  72.   SegTableRec           = RECORD
  73.                             Start               : WORD;
  74.                             Size                : WORD;
  75.                             Flags               : WORD;
  76.                             MinSize             : WORD
  77.                           END;
  78.   FileOffset            = LONGINT;
  79.  
  80. PROCEDURE ReadOnly;
  81.   INLINE($C6/$06/FileMode/$A0);
  82.  
  83. PROCEDURE ReadWrite;
  84.   INLINE($C6/$06/FileMode/$02);
  85.  
  86. { ExeOfs returns the offset of the item V in the .EXE file of the currently   }
  87. { running program. Use this to get the offset of a configuration record that  }
  88. { is located in the .EXE file (remember that you must declare it as a typed   }
  89. { constant to include it in the .EXE file)                                    }
  90.  
  91. {$IFDEF DPMI }
  92. FUNCTION ExeOfs(CONST V) : FileOffset;
  93.   VAR
  94.     HeaderDOS   : ExeHeaderDOS;
  95.     HeaderOS2   : ExeHeaderOS2;
  96.     FIL         : FILE;
  97.     CodeSeg,Seg : WORD;
  98.     SegTab      : SegTableRec;
  99.  
  100.   BEGIN
  101.     ReadOnly;
  102.     ASSIGN(FIL,ParamStr(0)); RESET(FIL,1);
  103.     BLOCKREAD(FIL,HeaderDOS,SizeOf(ExeHeaderDOS));
  104.     IF HeaderDOS.Signature<>'MZ' THEN
  105.       ExeOfs:=-1
  106.     ELSE BEGIN
  107.       SEEK(FIL,HeaderDOS.NewExeHeaderOfs);
  108.       BLOCKREAD(FIL,HeaderOS2,SizeOf(ExeHeaderOS2));
  109.       IF HeaderOS2.Signature<>'NE' THEN
  110.         ExeOfs:=-1
  111.       ELSE BEGIN
  112.         ASM
  113.                 MOV     BX,WORD PTR V+2
  114.                 MOV     CX,SS
  115.                 CMP     BX,CX
  116.                 JE      @STACK
  117.                 XOR     AX,AX
  118.                 VERW    BX
  119.                 JZ      @OUT
  120.                 MOV     ES,BX
  121.                 MOV     AX,ES:[0000h]
  122.                 JMP     @OUT
  123.         @STACK: MOV     AX,HeaderOS2.EntrySS
  124.         @OUT:   MOV     CodeSeg,AX
  125.         END;
  126.         IF CodeSeg<>0 THEN BEGIN
  127.           SEEK(FIL,HeaderDOS.NewExeHeaderOfs+HeaderOS2.SegTableOfs+
  128.             PRED(CodeSeg)*SizeOf(SegTableRec));
  129.           BLOCKREAD(FIL,SegTab,SizeOf(SegTableRec)) END
  130.         ELSE BEGIN
  131.           SEEK(FIL,HeaderDOS.NewExeHeaderOfs+HeaderOS2.SegTableOfs);
  132.           FOR Seg:=1 TO HeaderOS2.SegmentTableEntries DO BEGIN
  133.             BLOCKREAD(FIL,SegTab,SizeOf(SegTableRec));
  134.             IF (SegTab.Start>0) AND (SegTab.Flags AND $0001=$0001) THEN BREAK
  135.           END
  136.         END;
  137.         ExeOfs:=SegTab.Start SHL HeaderOS2.AlignmentUnitPower+OFS(V)
  138.       END
  139.     END;
  140.     CLOSE(FIL);
  141.     ReadWrite
  142.   END;
  143. {$ELSE }
  144. FUNCTION ExeOfs(CONST V) : FileOffset;
  145.   VAR
  146.     HeaderDOS   : ExeHeaderDOS;
  147.     FIL         : FILE;
  148.  
  149.   BEGIN
  150.     ReadOnly;
  151.     ASSIGN(FIL,ParamStr(0)); RESET(FIL,1);
  152.     BLOCKREAD(FIL,HeaderDOS,SizeOf(ExeHeaderDOS));
  153.     CLOSE(FIL);
  154.     ExeOfs:=(HeaderDOS.HeaderSizePara+(SEG(V)-(PrefixSeg+$0010)))*16+OFS(V)
  155.   END;
  156. {$ENDIF }
  157.